import React, { Component } from "react"
import { deepCopy, messages } from "share/common"
import SearchArea from "components/search-area"
import Table from "components/table"
import { message, Button, Tag, Icon, Row, Col, Collapse } from 'antd'
import httpFetch from "share/httpFetch";
import errorMessage from "share/errorMessage";
import chooserData from "share/chooserData";

const Panel = Collapse.Panel;

class ChooserContent extends Component {

  constructor(props) {
    super(props);
    this.state = {
      loading: true,
      data: [],
      page: 0,
      pageSize: 10,
      pagination: {
        total: 0,
        showSizeChanger: true,
        pageSizeOptions: ['10', '50', '100']
      },
      selectedData: this.props.value,  //已经选择的数据项
      selectorItem: {},  //当前的选择器类型数据项, 包含url、searchForm、columns
      searchParams: {},  //搜索需要的参数
      rowSelection: {
        type: props.single ? 'radio' : 'checkbox',
        selectedRowKeys: [],
        onChange: this.onSelectChange,
        onSelect: this.onSelectItem,
        onSelectAll: this.onSelectAll
      },
      history: []
    };
  }

  componentDidMount() {
    const { historyKey, type, onRef } = this.props;
    if (historyKey) {
      let localRecord = localStorage.getItem(`chooser_history_${historyKey}`);
      if (localRecord) {
        try {
          let data = JSON.parse(localRecord);
          this.setState({ history: Array.isArray(data) ? data : [] });
        } catch (e) {}
      }
    }
    onRef && onRef(this);
    this.checkType(type);
  }

  checkType = type => {
    let selectorItem = deepCopy(chooserData[type]);
    if(selectorItem){
      this.checkSelectorItem(selectorItem)
    }
  };

  checkSelectorItem = selectorItem => {
    let searchParams = {};
    selectorItem.searchForm.map(form => {
      searchParams[form.id] = form.defaultValue;  //遍历searchForm，取id组装成searchParams
      if(form.type === 'select' && form.defaultValue && form.defaultValue.key){
        searchParams[form.id] = form.defaultValue.key;
      }
    });
    this.setState({ selectorItem, searchParams }, () => {
      this.getList();
    })
  };

  getDataLabel = (data, keys) => {
    let length = keys.split('.').length;
    keys && keys.split('.').map((key, index) => {
      if(length - 1 !== index){
        data = data[key];
      }
    });
    return data;
  };

  getLastKey = key => {
    return key.split('.')[key.split('.').length - 1];
  };

  getList = () => {
    const { filterSearchParams, extraParams } = this.props;
    const { page, pageSize } = this.state;
    let selectorItem = this.state.selectorItem;
    let searchParams = Object.assign({}, this.state.searchParams, extraParams);
    let { url, service, map } = selectorItem;
    if (typeof url === 'function') {
      url = url()
    }
    let reg = /\?+/;
    if (reg.test(url)) {
      //检测是否已经有参数了，如果有直接加&
      url = `${url}&page=${page}&size=${pageSize}`;
    } else {
      url = `${url}?page=${page}&size=${pageSize}`;
    }
    filterSearchParams && filterSearchParams(searchParams);
    this.setState({ loading: true });
    let fetch = service ? service(page, pageSize) : httpFetch[this.props.method](url, searchParams);
    return fetch.then(response => {
      let data = [];
      if (map) {
        data = map(response.data);
      } else {
        data = selectorItem.listKey ? response.data[selectorItem.listKey] : response.data;
        let tmpData = [];
        data.map(item => {
          tmpData.push(this.getDataLabel(item, selectorItem.key))
        });
        data = tmpData;
        data.map(item => {
          item.key = item[this.getLastKey(selectorItem.key)];
        });
      }
      let pagination = {
        total: Number(response.headers['x-total-count']),
        showSizeChanger: true,
        onShowSizeChange: this.onChangePagerSize,
        onChange: this.onChangePager,
        current: this.state.page + 1,
        pageSize: this.state.pageSize,
        pageSizeOptions: ['10', '50', '100']
      };
      if (!Number(response.headers['x-total-count']) && typeof selectorItem.listKey !== 'undefined') {
        pagination.total = response.data.total || response.data[selectorItem.listKey].length
      }
      this.setState({
        data: data,
        loading: false,
        pagination
      }, () => {
        this.refreshSelected();  //刷新当页选择器
      })
    }).catch(e => {
      let pagination = {
        total: 0,
        showSizeChanger: true,
        onShowSizeChange: this.onChangePagerSize,
        onChange: this.onChangePager,
        current: 1,
        pageSize: this.state.pageSize,
        pageSizeOptions: ['10', '50', '100']
      };
      this.setState({
        data: [],
        loading: false,
        pagination
      }, () => {
        this.refreshSelected();  //刷新当页选择器
      });
      // '获取数据失败，请稍后重试或联系管理员'
      errorMessage(e.response, messages('common.error1')/*获取数据失败，请稍后重试或联系管理员*/);
      this.setState({ loading: false })
    });
  };

  onChangePager = page => {
    if(page - 1 !== this.state.page)
      this.setState({
        page: page - 1,
        loading: true
      }, ()=>{
        this.getList();
      })
  };

  onChangePagerSize = (current, size) => {
    if(size !== this.state.pageSize)
      this.setState({
        page: 0,
        pageSize: size,
        loading: true
      }, ()=>{
        this.getList();
      })
  };

  refreshSelected = () => {
    let { valueKey } = this.props;
    let { selectorItem, selectedData, data, rowSelection } = this.state;
    let nowSelectedRowKeys = [];
    selectedData.map(selected => {
      data.map(item => {
        if(item[this.getLastKey(valueKey || selectorItem.key)] === selected[this.getLastKey(valueKey || selectorItem.key)])
          nowSelectedRowKeys.push(item[this.getLastKey(selectorItem.key)])
      })
    });
    rowSelection.selectedRowKeys = nowSelectedRowKeys;
    this.setState({ rowSelection });
  };

  //选项改变时的回调，重置selection
  onSelectChange = selectedRowKeys => {
    let { rowSelection } = this.state;
    if (!(this.props.maxNum && this.props.maxNum > 0 && selectedRowKeys.length > this.props.maxNum)) {
      rowSelection.selectedRowKeys = selectedRowKeys
    }
    this.setState({ rowSelection });
  };

  /**
   * 选择单个时的方法，遍历selectedData，根据是否选中进行插入或删除操作
   * @param record 被改变的项
   * @param selected 是否选中
   */
  onSelectItem = (record, selected) => {
    let { valueKey } = this.props;
    let { selectedData, selectorItem } = this.state;
    if(this.props.single){
      selectedData = [record];
    } else {
      let key = this.getLastKey(valueKey || selectorItem.key);
      if(!selected){
        selectedData.map((selected, index) => {
          if(selected[key] === record[key]){
            selectedData.splice(index, 1);
          }
        });
      } else {
        if (this.props.maxNum && this.props.maxNum > 0 && selectedData.length >= this.props.maxNum) {
          message.warning(messages('common.max.selected.data',{arg1: this.props.maxNum})/*最多选择 {arg1} 条数据*/)
        } else {
          selectedData.push(record)
        }
      }
    }
    this.setState({ selectedData });
  };

  //点击行时的方法，遍历遍历selectedData，根据是否选中进行遍历遍历selectedData和rowSelection的插入或删除操作
  handleRowClick = (record) => {
    let { valueKey, single } = this.props;
    let { selectedData, selectorItem, rowSelection } = this.state;
    if (single) {
      selectedData = [record];
      rowSelection.selectedRowKeys = [record[this.getLastKey(selectorItem.key)]]
    } else {
      let haveIt = false;
      selectedData.map((selected, index) => {
        if(selected[this.getLastKey(valueKey || selectorItem.key)] === record[this.getLastKey(valueKey || selectorItem.key)]){
          selectedData.splice(index, 1);
          haveIt = true;
        }
      });
      if(!haveIt){
        if (this.props.maxNum && this.props.maxNum > 0 && selectedData.length >= this.props.maxNum) {
          message.warning(messages('common.max.selected.data',{arg1: this.props.maxNum})/*最多选择 {arg1} 条数据*/)
        } else {
          selectedData.push(record);
          rowSelection.selectedRowKeys.push(record[this.getLastKey(selectorItem.key)])
        }
      } else {
        rowSelection.selectedRowKeys.map((item, index) => {
          if((item + '') === (record[this.getLastKey(selectorItem.key)] + '')){
            rowSelection.selectedRowKeys.splice(index, 1);
          }
        })
      }
    }
    this.setState({ selectedData, rowSelection });
  };

  //选择当页全部时的判断
  onSelectAll = (selected, selectedRows, changeRows) => {
    if (this.props.maxNum && this.props.maxNum > 0 && changeRows.length + this.state.selectedData.length > this.props.maxNum && selected) {
      message.warning(messages('common.max.selected.data',{arg1: this.props.maxNum})/*最多选择 {arg1} 条数据*/);
    } else {
      changeRows.map(changeRow => this.onSelectItem(changeRow, selected))
    }
  };

  closeTag = (e, record) => {
    e.preventDefault();
    this.handleRowClick(record)
  };

  search = params => {
    const { filterSearchParams } = this.props;
    filterSearchParams && (params = filterSearchParams(params));
    this.setState({
      page: 0,
      searchParams: params,
      loading: true
    }, () => {
      this.getList();
    })
  };

  clear = () => {
    let searchParams = {};
    this.state.selectorItem.searchForm.map(form => {
      if (form.type === 'select' && form.defaultValue && form.defaultValue.key) {
        searchParams[form.id] = form.defaultValue.key;
      } else {
        searchParams[form.id] = form.defaultValue;
      }
    });
    this.setState({
      page: 0,
      searchParams: searchParams
    }, () => {
      this.getList();
    })
  };

  onClearHistory = e => {
    e.stopPropagation();
    const { historyKey } = this.props;
    localStorage.setItem(`chooser_history_${historyKey}`, JSON.stringify([]));
    this.setState({ history: [] });
  };

  onSelectHistory = item => {
    let { selectedData, rowSelection, selectorItem } = this.state;
    const { valueKey, maxNum } = this.props;
    const { key } = selectorItem;
    let targetKey = valueKey || key;
    let nextKey = item[this.getLastKey(targetKey)];
    if(!selectedData.find(s => s[this.getLastKey(targetKey)] === nextKey)) {
      if(maxNum <= selectedData.length) {
        message.warning(messages('common.max.selected.data',{arg1: maxNum})/*最多选择 {arg1} 条数据*/);
        return ;
      } else {
        selectedData.push(item);
        rowSelection.selectedRowKeys.push(nextKey);
      }
    } else {
      selectedData = selectedData.filter(s => s[this.getLastKey(targetKey)] !== nextKey);
      rowSelection.selectedRowKeys.delete(nextKey);
    }
    this.setState({ selectedData, rowSelection });
  };

  handleOk = () => {
    const { labelKey, valueKey } = this.props;
    const { selectedData } = this.state;
    return selectedData.map(item => ({
      [valueKey]: item[valueKey],
      [labelKey]: item[labelKey]
    }))
  };

  render () {
    const {
      selectAll, selectAllLoading, onSelectAll, historyKey, showDetail, labelKey, showArrow, valueKey,
      locale, beforeTable, eventHandle, extraHeader, extraBottom
    } = this.props;
    const {
      data, pagination, loading, selectorItem, selectedData, rowSelection, history
    } = this.state;
    const { searchForm, columns, key } = selectorItem;
    let localeAttr = locale ? { locale } : {};
    let hasLeft = searchForm && searchForm.length > 0 || historyKey || extraHeader;
    return (
      <Row className={'list-selector'}>
        {hasLeft && (
          <Col className='list-selector-left' span={6}>
            {extraHeader && extraHeader(selectedData)}
            {
              historyKey && (
                <Collapse defaultActiveKey='history'>
                  <Panel
                    header={(
                      <div>
                        {messages('common-1.key76')/*历史记录*/}
                        <span
                          className='clear-history'
                          onClick={this.onClearHistory}
                        >
                        {messages('common.clear')/*清空*/}
                      </span>
                      </div>
                    )}
                    key='history'
                  >
                    <div className='list-selector-left-history'>
                      {history.length > 0 ? history.map(item => (
                        <Tag
                          key={item[this.getLastKey(valueKey || key)]}
                          onClick={() => this.onSelectHistory(item)}
                          className={this.classNames({
                            'selected-history-tag': selectedData.find(data =>
                              item[this.getLastKey(valueKey || key)] ===
                              data[this.getLastKey(valueKey || key)]
                            )
                          })}
                        >
                          {item[labelKey]}
                        </Tag>
                      )) : messages('common-1.key77')/*暂无*/}
                    </div>
                  </Panel>
                </Collapse>
              )}
            {searchForm && searchForm.length > 0 && (
              <div>
                <div className='search-form-header'>{messages('common-1.key78')/*搜索条件*/}</div>
                <SearchArea
                  searchForm={searchForm}
                  isReturnLabel
                  submitHandle={this.search}
                  clearHandle={this.clear}
                  horizontal
                  wrappedComponentRef={(inst) => this.formRef = inst}
                  eventHandle={eventHandle}
                />
              </div>
            )}
          </Col>
        )}
        <Col span={hasLeft ? 18 : 24} className='list-selector-right'>
          {beforeTable}
          <div className="table-header">
            <div className="table-header-title">
              {
                selectAll && (
                  <Button
                    style={{ marginRight: 10 }}
                    loading={selectAllLoading}
                    onClick={onSelectAll}
                    type="primary"
                  >
                    {messages('common.selectAll')/*选择全部*/}
                  </Button>
                )
              }
              {messages('common.total',{arg1: pagination.total||data.length})/*共搜索到 {arg1} 条数据*/}{/* 共 total 条数据 */}
              &nbsp;<span>/</span>&nbsp;
              {messages('common.total.selected',{arg1: selectedData.length===0?'0':selectedData.length})/*已选 {arg1} 条*/}{/* 已选 total 条 */}
            </div>
            {showDetail && (
              <div className="selected-tag">
                {selectedData.map((item, index) => (
                    <span key={item[this.getLastKey(valueKey || key)]}>
                        <Tag
                          closable
                          onClick={e => this.closeTag(e, item)}
                        >
                          {item[labelKey]}
                        </Tag>
                      {showArrow && index !== selectedData.length - 1 &&
                      <Icon type="arrow-right" style={{ marginRight: 8 }}/>}
                      </span>
                  )
                )}
              </div>
            )}
          </div>
          <div className='list-selector-table-container'>
            {columns && <Table
              columns={columns}
              onRow={record => ({ onClick: () => this.handleRowClick(record) })}
              dataSource={data}
              rowKey={record => record[this.getLastKey(key)]}
              pagination={pagination}
              loading={loading}
              rowClassName="chooser-table-row"
              bordered
              size="small"
              {...localeAttr}
              rowSelection={rowSelection}
              minSize={72}
            />}
          </div>
          {extraBottom}
        </Col>
      </Row>
    )
  }

  static defaultProps = {
    extraParams: {},
    single: false,
    method: 'get',
    selectAll: false,
    selectAllLoading: false,
    onSelectAll: () => {},
    showDetail: false,
    showArrow: false,
    eventHandle: () => {},
    beforeTable: null
  }

}

export default ChooserContent
